package com.pink.filter;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.pink.entity.dto.UserDto;
import com.pink.entity.enums.userRoleEnum;
import com.pink.exception.BusinessException;
import com.pink.service.UserService;
import com.pink.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Slf4j
public class JwtAuthorizeFilter extends OncePerRequestFilter {

    @Resource
    JwtUtils utils;

    @Resource
    UserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain){

        // 检查是否是/admin接口
        boolean isAdminPath = request.getRequestURI().startsWith("/admin");

        try {
            String authHeader = request.getHeader("Authorization");

            // 对于/admin接口，必须要有有效的Bearer token
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                if (isAdminPath) {
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Bearer token required");
                    return;
                }
                filterChain.doFilter(request, response);
                return;
            }

            // 解析JWT
            DecodedJWT jwt = utils.resolveJwt(authHeader);
            if (jwt == null) {
                if (isAdminPath) {
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Invalid token");
                    return;
                }
                filterChain.doFilter(request, response);
                return;
            }

            // 转换为用户信息
            UserDetails user = utils.toUser(jwt);
            Integer userId = utils.toId(jwt);

            //获取数据库中的用户信息
            UserDto dbUser = userService.getUserByuserId(userId);

            // 检查/admin接口的权限
            if (isAdminPath && !(dbUser.getUserRole().equals(userRoleEnum.USER_ADMIN.getCode())
                    ||dbUser.getUserRole().equals(userRoleEnum.USER_SYS.getCode())||
                    dbUser.getUserRole().equals(userRoleEnum.USER_SUPER_ADMIN.getCode()))) {
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Forbidden: Admin role required");
                return;
            }

            // 设置认证信息
            UsernamePasswordAuthenticationToken authentication =
                    new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authentication);
            request.setAttribute("userId", userId);

            filterChain.doFilter(request, response);

        } catch (Exception e) {
            log.error("JwtAuthorizeFilter error: ", e);
            SecurityContextHolder.clearContext();
            throw new BusinessException("Unauthorized: Bearer token required");
        }
    }
}
